import 'package:flutter_html/image_render.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:html/dom.dart' as dom;

void main() {
  group("asset uri matcher", () {
    ImageSourceMatcher matcher = assetUriMatcher();
    test("matches a full asset: uri", () {
      expect(_match(matcher, 'asset:some/asset.png'), isTrue);
    });
    test("matches asset: schema without path", () {
      expect(_match(matcher, 'asset:'), isTrue);
    });
    test("doesn't match literal host 'asset'", () {
      expect(_match(matcher, 'asset/faulty.path'), isFalse);
    });
    test("doesn't match null", () {
      expect(_match(matcher, null), isFalse);
    });
    test("doesn't match empty", () {
      expect(_match(matcher, ''), isFalse);
    });
  });
  group("default network source matcher", () {
    ImageSourceMatcher matcher = networkSourceMatcher();
    test("matches a full http uri", () {
      expect(_match(matcher, 'http://legacy.http/uri.png'), isTrue);
    });
    test("matches a full https uri", () {
      expect(_match(matcher, 'https://proper.https/uri'), isTrue);
    });
    test("matches http: schema without path", () {
      expect(_match(matcher, 'http:'), isTrue);
    });
    test("matches https: schema without path", () {
      expect(_match(matcher, 'http:'), isTrue);
    });
    test("doesn't match null", () {
      expect(_match(matcher, null), isFalse);
    });
    test("doesn't match empty", () {
      expect(_match(matcher, ''), isFalse);
    });
  });
  group("custom network source matcher", () {
    ImageSourceMatcher matcher = networkSourceMatcher(
      schemas: ['https'],
      domains: ['www.google.com'],
      extension: 'png',
    );
    test("matches schema, domain and extension", () {
      expect(
          _match(matcher,
              'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png'),
          isTrue);
    });
    test("doesn't match if schema is different", () {
      expect(
          _match(matcher,
              'http://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png'),
          isFalse);
    });
    test("doesn't match if domain is different", () {
      expect(
          _match(matcher,
              'https://google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png'),
          isFalse);
    });
    test("doesn't match if file extension is different", () {
      expect(
          _match(matcher,
              'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dppng'),
          isFalse);
    });
    test("doesn't match null", () {
      expect(_match(matcher, null), isFalse);
    });
    test("doesn't match empty", () {
      expect(_match(matcher, ''), isFalse);
    });
  });
  group("base64 image data uri matcher", () {
    ImageSourceMatcher matcher = base64DataUriMatcher();
    test("matches a full png base64 data uri", () {
      expect(
          _match(matcher,
              ''),
          isTrue);
    });
    test("matches a full jpeg base64 data uri", () {
      expect(
          _match(matcher,
              ''),
          isTrue);
    });
    test("matches base64 data uri without data", () {
      expect(_match(matcher, 'data:image/png;base64,'), isTrue);
    });
    test("doesn't match non-base64 image data uri", () {
      expect(
          _match(matcher,
              'data:image/png;hex,89504e470d0a1a0a0000000d49484452000000050000000508060000008d6f26e50000001c4944415408d763f8ffff3fc37f062005c3201284d031f18258cd04000ef535cbd18e0e1f0000000049454e44ae426082'),
          isFalse);
    });
    test("doesn't match base64 non-image data uri", () {
      expect(_match(matcher, 'data:text/plain;base64,'), isFalse);
    });
    test("doesn't non-data schema", () {
      expect(_match(matcher, 'http:'), isFalse);
    });
    test("doesn't match null", () {
      expect(_match(matcher, null), isFalse);
    });
    test("doesn't match empty", () {
      expect(_match(matcher, ''), isFalse);
    });
  });
}

dom.Element _fakeElement(String src) {
  return dom.Element.html("""
      <img src="$src" />
    """);
}

bool _match(ImageSourceMatcher matcher, String src) {
  final element = _fakeElement(src);
  return matcher.call(
      element.attributes.map((key, value) => MapEntry(key.toString(), value)),
      element);
}
